/************************************************************************
* Programmer:  Philippe Gambling
*
* Course:  CSCI 4534
*
* Date:  February 18, 2009
*
* Assignment:  #1
*
* Environment:  GCC 3.2.2 running on diamond.rocks.uhcl.edu
*
* Files Included: client.c, server.c, fifomsg.h
*
* Purpose:  To read an integer from the user, send the value to the server,
*            and receive the calculated average integer from the server.
*
* Input:  An integer value from the user when prompted.
*
* Preconditions:  The server program is already running and FIFO_TO_SERVER exists.
*
* Output:  The average of all the client integer values calculated by the server.
*
* Postconditions:  After outputting the average, the client program deletes FIFO_PID and exits.        
*
* Algorithm:
*          Get the process ID (PID)
*          Create a private FIFO named "FIFO_PID", where PID is the process id number.
*          Open FIFO_TO_SERVER as write only
*          Prompt user to enter an integer value
*          Create a new fifomsg stuct
*          Assign the fifomsg's clientID to PID and copy the integer to fifomsg's param element
*          Write the fifomsg to FIFO_TO_SERVER
*          Open the FIFO_PID as read only
*          Read a fifomsg from FIFO_PID
*          Print returned param and calculated average from server to screen
*          Close FIF0_TO_SERVER and FIFO_PID
*          Unlink FIFO_PID
***********************************************************************/ 


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <fcntl.h>

extern int errno;

/* Custom includes created for this assignment */
#include "fifomsg.h"  // Defines a struct to send data to server

/* Function prototypes */
void CreatePrivateFifo(char *);

int main (void)
{
  int fda;			// to write to server
  int fdb;			// to read response from server
  fifomsg toServer = {{0},0,0};
  fifomsg fromServer = {{0},0,0};

  // Create a private FIFO to server to client communcation
  CreatePrivateFifo(toServer.clientFifoName);

  // Open FIFO_TO_SERVER to send data to server 
  printf("Client: Opening FIFO_TO_SERVER to write\n");
  if((fda=open("FIFO_TO_SERVER", O_WRONLY))<0)
     printf("cant open FIFO_TO_SERVER to write\n");

  // Get integer from user
  printf("Client: Please enter an integer: ");
  scanf("%d", &toServer.param);
  
  printf("Client: Sending the following message to server: \n");
  printf("        clientFifoName: %s\n",toServer.clientFifoName);
  printf("        param: %d\n",toServer.param);
  printf("        result: %f\n",toServer.result);    
  write(fda, &toServer, sizeof(fifomsg)); // Send data to server
  printf("Client: Sent data to server\n");
  
  // Open clientFifoName to receive data from server
  printf("Client: Opening %s to read server response\n", toServer.clientFifoName);
  if((fdb=open(toServer.clientFifoName, O_RDONLY))<0)
	  printf("cant open %s to read", toServer.clientFifoName);
  
  printf("Client: Waiting for response...\n");
  while(read(fdb, &fromServer, sizeof(fifomsg))<=0); // Get average from server
  
  printf("Client: Got the response from server\n");
  printf("Client: Input value received is %d\n", fromServer.param);
  printf("Client: Average returned from server is %f\n", fromServer.result);
 
  // Close FIFOs
  close(fda);
  close(fdb);
  
  // Clean up private fifo
  unlink(toServer.clientFifoName);

  printf ("Client: All done!\n");
 
  return 0;
}
void CreatePrivateFifo(char * fifoName)
/************************************************************************
* Purpose:  To create a FIFO name "FIFO_PID", where PID is the current
*           process's ID.
*
* Parameters:  A string to return the new FIFO's name.
*
* Action:  The fifo is written to fifoname.
*
***********************************************************************/ 
{ 
  sprintf(fifoName, "FIFO_%d", (int)getpid());
  
  printf("Client: FIFO name is %s \n", fifoName);
  if ((mkfifo(fifoName,0666)<0 && errno != EEXIST))
  {
	  perror("cant create private fifo");
	  exit(-1);
  }
  printf("Client: Succesfully created %s \n", fifoName); 
}
